package 多线程;

import java.util.concurrent.Semaphore;

/**
 * 该类用于实现A、B、C三个字母的交替打印。
 * 使用Semaphore实现线程间的同步，确保按顺序打印。
 * 时间复杂度：O(n)，空间复杂度：O(1)
 */
public class PrintABCUsingSemaphore {
    private int times; // 打印次数
    private static Semaphore semaphoreA = new Semaphore(1); // 信号量A，初始值为1
    private static Semaphore semaphoreB = new Semaphore(0); // 信号量B，初始值为0
    private static Semaphore semaphoreC = new Semaphore(0); // 信号量C，初始值为0

    /**
     * 构造函数，初始化打印次数。
     * @param times 打印次数
     */
    public PrintABCUsingSemaphore(int times) {
        this.times = times;
    }

    /**
     * 打印字母的方法。
     * 使用信号量确保按顺序打印A、B、C。
     * @param name 要打印的字母
     * @param current 当前信号量
     * @param next 下一个信号量
     */
    private void print(String name, Semaphore current, Semaphore next) {
        for(int i = 0; i < times; i++) {
            try {
                System.out.println("111" + Thread.currentThread().getName()); // 打印当前线程名称
                current.acquire(); // 获取当前信号量
                System.out.println(name); // 打印字母
                next.release(); // 释放下一个信号量
                System.out.println("222" + Thread.currentThread().getName()); // 打印当前线程名称
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 主方法，启动三个线程分别打印A、B、C。
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        PrintABCUsingSemaphore printer = new PrintABCUsingSemaphore(3);
        new Thread(() -> {
            printer.print("a", semaphoreA, semaphoreB);
        }, "a").start(); // 启动打印A的线程
        new Thread(() -> {
            printer.print("b", semaphoreB, semaphoreC);
        }, "b").start(); // 启动打印B的线程
        new Thread(() -> {
            printer.print("c", semaphoreC, semaphoreA);
        }, "c").start(); // 启动打印C的线程
    }
}
